import { BoltronPlugin } from '../types';
import { BoltronApplication } from '../core/BoltronApplication';
import { DevTools, DevToolsOptions } from '../utils/DevTools';
import { ipcMain } from 'electron';

/**
 * 开发者工具插件
 * 提供高级调试和性能分析功能
 */
export class DevToolsPlugin implements BoltronPlugin {
  /**
   * 插件名称
   */
  public readonly name = 'devTools';
  
  /**
   * 开发者工具配置
   */
  private options: DevToolsOptions;
  
  /**
   * 开发者工具实例
   */
  private devTools: DevTools;
  
  /**
   * 应用实例引用
   */
  private app?: BoltronApplication;
  
  /**
   * 原始的 ipcMain.handle 方法
   */
  private originalIpcMainHandle: typeof ipcMain.handle;
  
  /**
   * 创建开发者工具插件
   * @param options 开发者工具配置
   */
  constructor(options: DevToolsOptions = {}) {
    this.options = {
      enabled: process.env.NODE_ENV !== 'production',
      openAtStartup: false,
      mode: 'right',
      networkMonitoring: true,
      performanceMonitoring: true,
      logIpcMessages: true,
      extensions: [],
      ...options
    };
    
    // 在构造函数中直接创建 DevTools 实例
    this.devTools = new DevTools(this.options);
    
    // 保存原始的 handle 方法
    this.originalIpcMainHandle = ipcMain.handle;
  }
  
  /**
   * 初始化插件
   * @param app Boltron 应用实例
   */
  async init(app: BoltronApplication): Promise<void> {
    this.app = app;
    
    console.log('开发者工具插件初始化中...');
    
    // 拦截 IPC 调用
    this.interceptIpcCommunication();
    
    // 注册 IPC 处理器
    this.registerIpcHandlers();
    
    // 为现有窗口应用开发者工具
    this.setupForExistingWindows();
    
    // 监听窗口创建事件
    this.monitorWindowCreation();
    
    console.log('开发者工具插件初始化完成');
  }
  
  /**
   * 拦截 IPC 通信
   */
  private interceptIpcCommunication(): void {
    if (!this.options.logIpcMessages) return;
    
    // 重写 ipcMain.handle 方法，用于拦截 IPC 调用
    ipcMain.handle = (channel: string, listener: (event: Electron.IpcMainInvokeEvent, ...args: any[]) => Promise<any> | any) => {
      // 创建一个新的监听器，包装原始监听器
      const wrappedListener = async (event: Electron.IpcMainInvokeEvent, ...args: any[]) => {
        // 记录请求
        this.devTools.logIpcMessage(channel, args, 'renderer->main');
        
        try {
          // 调用原始监听器
          const result = await listener(event, ...args);
          
          // 记录响应
          this.devTools.logIpcMessage(channel, [result], 'main->renderer');
          
          return result;
        } catch (error) {
          // 记录错误
          this.devTools.logIpcMessage(`${channel}:error`, [error], 'main->renderer');
          throw error;
        }
      };
      
      // 调用原始 handle 方法
      return this.originalIpcMainHandle.call(ipcMain, channel, wrappedListener);
    };
  }
  
  /**
   * 注册 IPC 处理器
   */
  private registerIpcHandlers(): void {
    if (!this.app) return;
    
    this.app.registerIpcHandler('devTools', {
      /**
       * 获取 IPC 通信日志
       */
      getIpcLogs: () => {
        return this.devTools.getIpcLogs();
      },
      
      /**
       * 清空 IPC 通信日志
       */
      clearIpcLogs: () => {
        this.devTools.clearIpcLogs();
        return true;
      },
      
      /**
       * 获取所有注册的 IPC 方法
       */
      getRegisteredMethods: () => {
        return this.app?.getIpcHandler('devTools') ? 
          Object.keys(this.app.getIpcHandler('devTools') as any) : [];
      },
      
      /**
       * 打开指定窗口的开发者工具
       */
      openDevTools: (windowName: string, mode?: 'right' | 'bottom' | 'undocked' | 'detach') => {
        const window = this.app?.getWindow(windowName);
        if (window) {
          const nativeWindow = window.getNativeWindow();
          nativeWindow.webContents.openDevTools({ mode: mode || 'right' });
          return true;
        }
        return false;
      },
      
      /**
       * 关闭指定窗口的开发者工具
       */
      closeDevTools: (windowName: string) => {
        const window = this.app?.getWindow(windowName);
        if (window) {
          const nativeWindow = window.getNativeWindow();
          nativeWindow.webContents.closeDevTools();
          return true;
        }
        return false;
      },
      
      /**
       * 获取开发者工具状态
       */
      getStatus: () => {
        return {
          enabled: this.options.enabled,
          mode: this.options.mode,
          version: '1.0.0',
          networkMonitoring: this.options.networkMonitoring,
          performanceMonitoring: this.options.performanceMonitoring,
          logIpcMessages: this.options.logIpcMessages
        };
      },
      
      /**
       * 获取性能指标
       */
      getPerformanceMetrics: async () => {
        return {
          timestamp: Date.now(),
          memory: process.memoryUsage(),
          uptime: process.uptime(),
          cpuUsage: process.cpuUsage()
        };
      },
      
      /**
       * 捕获当前应用状态快照
       */
      captureSnapshot: () => {
        if (!this.app) return { timestamp: Date.now() };
        
        return {
          timestamp: Date.now(),
          windows: this.app.getAllWindows().map(window => ({
            id: window.getId(),
            name: window.getName(),
            isDestroyed: window.isDestroyed()
          })),
          ipcMethods: this.app.getIpcHandler('devTools') ? 
            Object.keys(this.app.getIpcHandler('devTools') as any) : [],
          ipcLogs: this.devTools.getIpcLogs()
        };
      }
    });
  }
  
  /**
   * 为现有窗口应用开发者工具
   */
  private setupForExistingWindows(): void {
    if (!this.app) return;
    
    const windows = this.app.getAllWindows();
    for (const window of windows) {
      const nativeWindow = window.getNativeWindow();
      this.devTools.setup(nativeWindow);
    }
  }
  
  /**
   * 监听窗口创建
   */
  private monitorWindowCreation(): void {
    if (!this.app || !this.options.enabled) return;
    
    // 使用猴子补丁替换 BoltronApplication 的 createWindow 方法
    const originalCreateWindow = this.app.createWindow.bind(this.app);
    const devTools = this.devTools;
    
    // @ts-ignore - 替换方法
    this.app.createWindow = function(name: string, options: any) {
      const windowOrPromise = originalCreateWindow(name, options);
      
      if (windowOrPromise instanceof Promise) {
        // 如果返回的是Promise，则在Promise中设置开发者工具
        return windowOrPromise.then(window => {
          const nativeWindow = window.getNativeWindow();
          devTools.setup(nativeWindow);
          return window;
        });
      } else {
        // 否则直接设置开发者工具
        const nativeWindow = windowOrPromise.getNativeWindow();
        devTools.setup(nativeWindow);
        return windowOrPromise;
      }
    };
  }
  
  /**
   * 获取开发者工具实例
   */
  public getDevTools(): DevTools {
    return this.devTools;
  }
  
  /**
   * 销毁插件
   */
  async destroy(): Promise<void> {
    console.log('开发者工具插件卸载中...');
    
    // 恢复原始的 IPC handle 方法
    if (this.originalIpcMainHandle) {
      ipcMain.handle = this.originalIpcMainHandle;
    }
    
    if (this.app) {
      // 移除 IPC 处理器
      this.app.removeIpcHandler('devTools');
      
      // 恢复原始的 createWindow 方法（如果被修改）
      const originalApp = this.app as any;
      if (originalApp._originalCreateWindow) {
        originalApp.createWindow = originalApp._originalCreateWindow;
      }
    }
    
    console.log('开发者工具插件已卸载');
  }
} 